/**
 * Copyright (c) Huawei Technologies Co., Ltd. 2012-2018. All rights reserved.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 */

#include "utils.h"
#include "acl/acl.h"
#include "aicl.h"
#include <sys/time.h>
#include <sys/stat.h>

using namespace std;

void *Utils::ReadBinFile(std::string fileName, uint32_t &fileSize)
{
    std::ifstream binFile(fileName, std::ifstream::binary);
    if (binFile.is_open() == false) {
        ERROR_LOG("open file %s failed", fileName.c_str());
        return nullptr;
    }

    binFile.seekg(0, binFile.end);
    uint32_t binFileBufferLen = binFile.tellg();
    if (binFileBufferLen == 0) {
        ERROR_LOG("binfile is empty, filename is %s", fileName.c_str());
        binFile.close();
        return nullptr;
    }

    binFile.seekg(0, binFile.beg);

    void *binFileBufferData = nullptr;
    aiclrtMallocHost(&binFileBufferData, binFileBufferLen);
    if (binFileBufferData == nullptr) {
        ERROR_LOG("malloc binFileBufferData failed");
        binFile.close();
        return nullptr;
    }

    binFile.read(static_cast<char *>(binFileBufferData), binFileBufferLen);
    binFile.close();
    fileSize = binFileBufferLen;
    return binFileBufferData;
}

void *Utils::GetDeviceBufferOfFile(std::string fileName, uint32_t &fileSize)
{
    uint32_t inputHostBuffSize = 0;
    void *inputHostBuff = Utils::ReadBinFile(fileName, inputHostBuffSize);
    if (inputHostBuff == nullptr) {
        return nullptr;
    }

    void *inBufferDev = nullptr;
    uint32_t inBufferSize = inputHostBuffSize;
    aiclRet ret = aiclrtMalloc(&inBufferDev, inBufferSize, AICL_MEM_MALLOC_NORMAL_ONLY);
    if (ret != AICL_RET_SUCCESS) {
        ERROR_LOG("malloc device buffer failed. size is %u", inBufferSize);
        aiclrtFreeHost(inputHostBuff);
        return nullptr;
    }

    ret = aiclrtMemcpy(inBufferDev, inBufferSize, inputHostBuff, inputHostBuffSize, AICL_MEMCPY_HOST_TO_DEVICE);
    if (ret != AICL_RET_SUCCESS) {
        ERROR_LOG("memcpy failed. device buffer size is %u, input host buffer size is %u", inBufferSize,
            inputHostBuffSize);
        aiclrtFree(inBufferDev);
        aiclrtFreeHost(inputHostBuff);
        return nullptr;
    }
    aiclrtFreeHost(inputHostBuff);
    fileSize = inBufferSize;
    return inBufferDev;

}


